
package kuti.grp5;

import static java.lang.Math.pow;
import kuti.ILawnArea;
import kuti.ISimulParams;

/**
 * The ScoreManager class manage the score. It calculate the score of the
 * current simulation.
 *
 * @author Marc Schorderet <marc.schorderet@edu.hefr.ch>
 * @author Vincenzo Do <vincenzo.do@edu.hefr.ch>
 * 
 */

public class ScoreManager {
    
    /**
     * The lawn of the simulation
     */
    
    private int[][] lawn;
    
    /**
     * The max height of the blade
     */
    
    private double max;
    
    /**
     * The constructor create the score manager.
     * 
     * @param lawnArea      lawn area of the simulation
     * @param simulParams   simulation parameters
     * 
     */
    
    public ScoreManager(ILawnArea lawnArea, ISimulParams simulParams){
        
        // Check if the lawn area is valid
        if(lawnArea == null || lawnArea.getBladeHeight() == null){
            throw new IllegalArgumentException("The lawn area is not defined");
        }
        
        // Check if the simulation parameters are valid
        if(simulParams == null){
            throw new IllegalArgumentException("The simulation parameters are not defined");
        }
        
        int bladeMax = simulParams.getBladeHMax();
        
        // Check if the max height is valid
        if(bladeMax < 1){
            throw new IllegalArgumentException("The max blade height is not valid. " + 
                    " It must be greatter that 0. [current value: " + bladeMax + "]");
        }
        
        // get the lawn height
        lawn = lawnArea.getBladeHeight();
        
        // Square of the height
        max = pow(bladeMax, 2);
        
    }
    
    /**
     * This method calculate the score.
     * 
     * @return Returns the score.
     * 
     */
    
    public double getScore(){
        
        return 1.0 - (averageLawnHeight() / max);
    }
    
    /**
     * This method calculate the average lawn height.
     * 
     * @return Returns the average lawn height. 
     */
    
    private double averageLawnHeight() {

        // Initialization of the average
        double average = 0.0;

        for (int i = 0; i < lawn.length; i++) {

            // Initialization of the average per ligne
            double temp = 0.0;

            for (int j = 0; j < lawn[i].length; j++) {

                // Add the square of the height
                temp += lawn[i][j] * lawn[i][j];

            }

            // Calculate the average height of each row
            average += (temp / lawn[i].length);

        }

        // Calculate the mean of the height for the entire surface
        return average /= lawn.length;
    }
    
    
}